about goroutine
要聊 golang 中的 「go」 這個保留字之前,先來說說 Goroutine 這東東
在 golang 中,每一個併發的執行單元叫作一個 goroutine。
在現在這個時空背景之下, CPU 的時脈已經逼近物理上限,不管是 AMD 或是 Intel 都往多核、多線程發展。
同理,單一的大型伺服器相當昂貴,擴充不易,使用多台主機組成的叢集 (cluster) 成本比較容易控制。
but ... 若是 code 沒有用到 concurrency 來寫,就無法發揮平行處理 (parallel computing) 、無法享受到效能的提升。
Go 主要的特色之一,就在於其對併發性程式的支援;大部分程式語言以函式庫來支援共時性程式,但 Go 將其內建在語法中。
以 goroutine 做為併發執行的程式碼區塊,goroutine 類似於執行緒,但更輕量,一次啟動數百甚至數千個以上的 goroutine 也不會占用太多記憶體。要使用 goroutine,在函式前加上 go 關鍵字即可
用 goroutine 同時跑兩個任務
go mission1(ctx)
go mission2(ctx)
也可以用 for 迴圈起多個 goroutine
for i := 1; i <= 10; i++ {
go mission10(i)
}
about chan
如果說 goroutine 是 Golang 的併發體的話,那麼 channels 就是他們之間的通信機制。一個 channel 是一個通信機制。每個 channel 都有一個特殊的類型,也就是 channels 可發送數值的類型。一個可以發送 int 的 channel 一般寫為
chan int
channel 需要 make() 方法來創建
oneChannel := make(chan int)
當一個資料需要在 goroutine 之間共享時,通道在 goroutine 之間架起一個管道,並提供確保同步交換數據的機制。宣告通道時,需要指定將要被共享的資料型態。可以透過 channel 共享 int, float, struct, pointer ... 等資料型態。
通過 channel 發送訊息
使用 make 創建一個 channel 後,就可以使用<- 向channel 發送資料,例子如下:
// 準備一個空接口通道
demoChan := make(chan interface{})
// 把 0 放入通道中
demoChan <- 0
// 把 hello 字串放入 channel 中
demoChan1 <- "hello"
使用 channel 接收訊息
阻塞接收
阻塞模式接收數據時,將接收變數指定到 <- 的左邊的值
data := <-ch
非阻塞接收
data, ok := <-ch
//多了判斷是否接收到數據
任意接收
<-ch
循環接收
通道的數據接收可以用 for range 的遍歷方式
for data := range oneChannel {
}
select
select 是一種與 switch 相似的結構控制 but ....select 中雖然也有多個 case,但是這些 case 中的判斷式必須都是 Channel 的收發操作。